/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package quan;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

/**
 *
 * @author Quannk
 */
public class QOverviewPanel extends JPanel {

    private Point currentPoint;
    private QDesktopPane desktopPane;
    private Rectangle visibleRect;
    private boolean isMouseDragged = false;
    private boolean isSynchronizeScroll;

    private boolean isDrawVisibleRect() {
        boolean result = (visibleRect.width > 0 && visibleRect.height > 0) && (visibleRect.width < desktopPane.getPreferredSize().width
                || visibleRect.height < desktopPane.getPreferredSize().height);
        return result;
    }

    public boolean isIsSynchronizeScroll() {
        return isSynchronizeScroll;
    }

    public void setIsSynchronizeScroll(boolean isSynchronizeScroll) {
        this.isSynchronizeScroll = isSynchronizeScroll;
    }

    public Rectangle getVisibleRect() {
        return visibleRect;
    }

    public void setVisibleRect(Rectangle rect) {
        this.visibleRect = rect;
        repaint();
    }

    public void setDesktopPane(QDesktopPane desktopPane) {
        this.desktopPane = desktopPane;
    }

    public QOverviewPanel() {
        initMouseListener();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Image newImage = getImageScaled();
        g.drawImage(newImage, 0, 0, null);
        if (isDrawVisibleRect()) {
            if (!isMouseDragged) {
                updateRect(newImage);
            }
            g.drawRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height);
        }
    }

    private Image getImageScaled() {
        BufferedImage img = QUtility.getImage(desktopPane);
        int w, h;
        w = img.getWidth();
        h = img.getHeight();
        Image newImage = null;
        if (w > this.getWidth()) {
            newImage = img.getScaledInstance(this.getWidth(), -1, Image.SCALE_DEFAULT);
            h = newImage.getHeight(null);
        }
        if (h > this.getHeight()) {
            newImage = img.getScaledInstance(-1, this.getHeight(), Image.SCALE_DEFAULT);
        }
        return newImage;


    }

    private void updateRect(Image newImage) {
        double scaleX = (double) visibleRect.width / (double) desktopPane.getPreferredSize().getWidth();
        double scaleY = (double) visibleRect.height / (double) desktopPane.getPreferredSize().getHeight();
        double scaleX1 = (double) newImage.getWidth(null) / (double) desktopPane.getPreferredSize().getWidth();
        double scaleY1 = (double) newImage.getHeight(null) / (double) desktopPane.getPreferredSize().getHeight();
        visibleRect.x = (int) (visibleRect.x * scaleX1);
        visibleRect.y = (int) (visibleRect.y * scaleY1);
        visibleRect.width = (int) (newImage.getWidth(null) * scaleX);
        visibleRect.height = (int) (newImage.getHeight(null) * scaleY);
    }

    private void initMouseListener() {
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if (!visibleRect.contains(e.getPoint())) {
                    return;
                }
                isMouseDragged = true;
                if (currentPoint == null) {
                    currentPoint = e.getPoint();
                } else {
                    int x = e.getX() - currentPoint.x;
                    int y = e.getY() - currentPoint.y;
                    currentPoint = e.getPoint();
                    if (x + visibleRect.x + visibleRect.width > getWidth()) {
                        visibleRect.x = getWidth() - visibleRect.width;
                    } else if (x + visibleRect.x < 0) {
                        visibleRect.x = 0;
                    } else {
                        visibleRect.x = visibleRect.x + x;
                    }

                    if (y + visibleRect.y + visibleRect.height > getHeight()) {
                        visibleRect.y = getHeight() - visibleRect.height;
                    } else if (y + visibleRect.y < 0) {
                        visibleRect.y = 0;
                    } else {
                        visibleRect.y = visibleRect.y + y;
                    }
                    repaint();
//                    isSynchronizeScroll = true;
                    desktopPane.synchronizedScroll(new Point(visibleRect.x, visibleRect.y));

                }
            }
        });
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                super.mouseReleased(e);
                isMouseDragged = false;
                desktopPane.scrollPane.setSynchronizedScroll(false);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
//                isMoveVisibleRect = true;
//                if(e.getX() + visibleRect.width > getWidth())
//                    visibleRect.x = getWidth() - visibleRect.width;
//                else
//                    visibleRect.x = e.getX();
//                if(e.getY() + visibleRect.height > getHeight())
//                    visibleRect.y = getHeight() - visibleRect.height;
//                else
//                    visibleRect.y = e.getY();
//                repaint();
//                isSynchronizeScroll = true;
//                desktopPane.synchronizedScroll(new Point(visibleRect.x, visibleRect.y));
            }
            
        });
    }
}
